<template>
  <div class="intensity">
    <span class="line" :class="setClass('low')">弱</span>
    <span class="line" :class="setClass('middle')">中</span>
    <span class="line" :class="setClass('high')">强</span>
    <div class="warning-text">密码应由8-16位数字、字母、特殊字符组成。</div>
  </div>
</template>
<script lang="ts" setup>
import { ref, watch } from 'vue';

defineOptions({
  name: 'PasswordComplexity',
});
const props = defineProps({
  modelValue: { type: String, required: false },
});
const emit = defineEmits(['update:modelValue']);

const level = ref<string[]>([]);
const setClass = (type: string) => {
  if (level.value.includes('high')) {
    return 'high';
  } else if (level.value.includes('middle') && (type === 'low' || type === 'middle')) {
    return 'middle';
  } else if (level.value.includes('low') && type === 'low') {
    return 'low';
  }
  return '';
};
watch(
  () => props.modelValue,
  (newVal) => {
    const newPassword = newVal || '';
    if (newPassword && newPassword.length > 16) {
      return new Error('密码超过16位数');
    }

    level.value = [];
    //少于8位数为弱密码
    if (newPassword && newPassword.length < 8) {
      level.value.push('low');
    }
    if (/^\d+$/.test(newPassword) || /^[A-Za-z]+$/.test(newPassword) || /^[`~!@#$%^&*()_\-+=<>?:"{}|,.\/;'\\[\]·~！@#￥%……&*（）——\-+={}|《》？：“”【】、；‘'，。、]{8,16}$/.test(newPassword)) {
      level.value.push('low');
      return new Error('密码应由8-16位数字、字母、特殊字符组成。!');
    } else if (
      /^[`~!@#$%^&*()_\-+=<>?:"{}|,.\/;'\\[\]·~！@#￥%……&*（）——\-+={}|《》？：“”【】、；‘'，。、A-Za-z]{8,16}$/.test(newPassword) ||
      /^[`~!@#$%^&*()_\-+=<>?:"{}|,.\/;'\\[\]·~！@#￥%……&*（）——\-+={}|《》？：“”【】、；‘'，。、\d]{8,16}$/.test(newPassword) ||
      /^[A-Za-z\d]+$/.test(newPassword)
    ) {
      level.value.push('middle');
      return new Error('密码应由8-16位数字、字母、特殊字符组成。!');
    } else if (/^[`~!@#$%^&*()_\-+=<>?:"{}|,.\/;'\\[\]·~！@#￥%……&*（）——\-+={}|《》？：“”【】、；‘'，。、A-Za-z\d]{8,16}$/.test(newPassword)) {
      level.value.push('high');
    }
    emit('update:modelValue', newPassword);
  },
);
</script>
<style lang="scss" scoped>
.intensity {
  margin-top: 10px;
}

.line {
  display: inline-block;
  width: 48px;
  height: 4px;
  background: #d8d8d8;
  border-radius: 3px;
  margin-right: 8px;
  text-align: center;
  color: #5a5a5a;
  font-size: 12px;
}

.low {
  background: #f4664a;
}

.middle {
  background: #ffb700;
}

.high {
  background: #2cbb79;
}

.level {
  margin: 0 16px 0 10px;
}

.warning-text {
  color: #5a5a5a;
  font-size: 12px;
  margin-top: 5px;
}
</style>
